終於到了第二章的最後一個守則了!來看看吧!
今天的守則專注於copy的部分,包含copy constructor跟copy assignment operator,而守則是:
Copy all parts of an object
一開始用很幽默的方式描述當你有漏掉copy內容時,compiler不會給你任何警告這件事。在前面的守則([Day 9] Know what functions C++ silently writes and calls)有提過compiler會自動生成copy constructor跟copy assignment operator,他們會copy所有可得的資料,除非你自行宣告─這就假設了原本自動生成的版本有你不認同的地方,所以,當你定義了任何荒謬不完整的copy function們,編譯器都不會理你XD 他覺得你有自己獨特的想法。所以,就必須自行注意要copy到所有的東西,避免 partial copy。
例如:
class Date {...};
class Customer
{
public:
Customer(const Customer& rhs);
Customer& operator=(const Customer& rhs);
private:
std::string name;
Date lastTransaction;
}
Customer::Customer(const Customer& rhs): name(rhs.name)
{
}
Customer& Customer::operator=(const Customer& rhs)
{
name = rhs.name;
}
上面的範例就沒有copy到lastTransaction
的部分。所以要注意每當加一個member,你自行宣告定義的copy function就都要補上。
另外一個陷阱就是在繼承的時候,很有可能會踩到:
class PriorityCustomer: public Customer
{
public:
PriorityCustomer(const PriorityCustomer& rhs);
PriorityCustomer& operator=(const PriorityCustomer& rhs);
private:
int priority;
}
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs): priority(rhs.priority)
{
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
priority = rhs.priority;
return *this;
}
看起來priority
有copy,那彷彿都有copy到,但從Customer
繼承來的data,其實都沒cover到啊!完全沒有帶到可以讓知道Customer
data的東西。
因此,在derived class的copying function,我們分外需要注意 base class部分的copy。又那些data大多都是private的,因此我們必須用base class的function來執行。例如以上可以改成:
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs): Customer(rhs), priority(rhs.priority)
{
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
Customer::operator=(rhs);
priority = rhs.priority;
return *this;
}
綜合以上,我們在copy時必須注意以下兩點:
其他部分,我們明天繼續看下去。